﻿using Away.IdentityServer.Core.Utils;

namespace Away.IdentityServer.Core.Repositories.Impl;

[ServiceInject(ServiceLifetime.Scoped)]
public class IdResourceRepository : ConfigurationRepository, IIdResourceRepository
{
    public IdResourceRepository(ConfigurationDbContext context) : base(context)
    {
    }

    public List<SelectItems> List()
    {
        return Query<IdentityResource>()
            .Select(o => new SelectItems
            {
                Value = o.Name,
                Label = o.DisplayName
            }).ToList();
    }

    public IResult Page(IdResourcesSearch search)
    {
        var where = CondBuilder.New<IdentityResource>(true)
           .And(!string.IsNullOrWhiteSpace(search.Name), o => o.Name.Contains(search.Name!));
        var query = Query<IdentityResource>()
            .Include(o => o.Properties)
            .Include(o => o.UserClaims)
            .Where(where);

        var total = query.Count();
        var items = query.OrderBy(o => o.Id).Page(search).ToList();
        return ApiResult.Page(total, items);
    }

    public void Remove(List<int> ids)
    {
        var items = Query<IdentityResource>().Where(o => ids.Any(oo => oo == o.Id)).ToArray();
        if (items.Length == 0)
        {
            return;
        }
        Remove(items);
        Save();
    }

    public void Save(IdentityResource model)
    {
        Update(model);
        Save();

        var propertyIds = model.Properties.Select(o => o.Id);
        var claimIds = model.UserClaims.Select(o => o.Id);

        var sql = SqlBuilder.New();
        sql.Delete("\"IdentityResourceProperties\"")
            .Where($"\"IdentityResourceId\"={model.Id}")
            .And(propertyIds.Any(), $"\"Id\" NOT IN ({string.Join(",", propertyIds)})")
            .End();

        sql.Delete("\"IdentityResourceClaims\"")
            .Where($"\"IdentityResourceId\"={model.Id}")
            .And(claimIds.Any(), $"\"Id\" NOT IN ({string.Join(",", claimIds)})")
            .End();

        DB.Database.ExecuteSqlRaw(sql.ToSql());
    }
}
